# -*- coding: utf-8 -*-
import socket
import threading
from datetime import datetime

from PyQt5.QtCore import pyqtSignal, QObject

from . import StopThreading


def get_timestamp():
    """获取当前时间戳"""
    return datetime.now().strftime("(%H:%M:%S)")


def get_host_ip() -> str:
    """获取本机IP地址"""
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("127.0.0.1", 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip


class UdpLogic(QObject):
    udp_signal_write_info = pyqtSignal(str, int)
    udp_signal_write_msg = pyqtSignal(str)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.udp_socket = None
        self.sever_th = None
        self.client_th = None
        self.link_flag = self.NoLink  # 用于标记是否开启了连接

    def udp_server_start(self, port) -> None:
        """
        开启UDP服务端方法
        """
        self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        port = int(port)
        address = ("", port)
        self.udp_socket.bind(address)
        self.sever_th = threading.Thread(target=self.udp_server_concurrency)
        self.sever_th.start()
        msg = f"{get_timestamp()} UDP服务端正在监听端口:{port}\n"
        self.udp_signal_write_msg.emit(msg)

    def udp_server_concurrency(self) -> None:
        """
        用于创建一个线程持续监听UDP端口
        """
        while True:
            try:
                recv_msg, recv_addr = self.udp_socket.recvfrom(1024)
            except Exception as ret:
                break
            try:
                info = recv_msg.decode("utf-8")
                msg = f"{get_timestamp()} 来自IP:{recv_addr[0]}端口:{recv_addr[1]}:"
                self.udp_signal_write_msg.emit(msg)
                self.udp_signal_write_info.emit(info, self.InfoRec)
            except Exception as ret:
                pass

    def udp_client_start(self, ip: str, port: int) -> None:
        """
        UDP客户端开启
        """
        self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.address = (ip, port)
        self.link_flag = self.ClientUDP
        msg = f"{get_timestamp()} UDP客户端已启动\n"
        self.udp_signal_write_msg.emit(msg)

    def udp_send(self, send_info: str) -> None:
        """
        UDP发送消息
        """
        try:
            send_info_encoded = send_info.encode("utf-8")
            self.udp_socket.sendto(send_info_encoded, self.address)
            msg = f"{get_timestamp()} UDP客户端已发送"
            print(msg)
            self.udp_signal_write_msg.emit(msg)
            self.udp_signal_write_info.emit(send_info, self.InfoSend)
        except Exception as ret:
            msg = f"{get_timestamp()} 发送失败\n"
            self.udp_signal_write_msg.emit(msg)

    def udp_close(self) -> None:
        """
        关闭UDP连接
        """
        if self.link_flag == self.ServerUDP:
            try:
                self.udp_socket.close()
                msg = f"{get_timestamp()} 已断开网络\n"
                self.udp_signal_write_msg.emit(msg)
            except Exception as ret:
                pass

            try:
                StopThreading.stop_thread(self.sever_th)
            except Exception:
                pass

        if self.link_flag == self.ClientUDP:
            try:
                self.udp_socket.close()
                msg = f"{get_timestamp()} 已断开网络\n"
                self.udp_signal_write_msg.emit(msg)
            except Exception as ret:
                pass

            try:
                StopThreading.stop_thread(self.client_th)
            except Exception:
                pass

    NoLink = -1
    ServerUDP = 2
    ClientUDP = 3
    InfoSend = 0
    InfoRec = 1
